<template>
  <div
    class="chat-at-box"
    v-if="visible"
    :style="{
      left: `${position.x}px`,
      top: `${position.y}px`,
      width: `${width}px`
    }"
    @mousedown.stop
  >
    <!-- 搜索框 -->
    <div class="search-container">
      <input
        type="text"
        v-model="searchQuery"
        placeholder="搜索成员..."
        class="search-input"
        @keydown.enter.prevent="selectCurrent"
        @keydown.up.prevent="moveUp"
        @keydown.down.prevent="moveDown"
        @keydown.esc="close"
        @keydown.tab.prevent="selectCurrent"
        ref="searchInput"
      />
    </div>

    <!-- 结果列表 -->
    <div
      class="results-container"
      :class="{ 'has-results': filteredMembers.length }"
    >
      <ul class="members-list">
        <li
          v-for="(member, index) in filteredMembers"
          :key="getMemberKey(member, index)"
          :class="{ active: activeIndex === index }"
          @click="selectMember(member)"
          @mouseenter="activeIndex = index"
        >
          <div class="member-avatar" v-if="member.avatar">
            <img :src="member.avatar" :alt="member.username" />
          </div>
          <div class="member-avatar default-avatar" v-else>
            {{ getInitials(member.username) }}
          </div>
          <div class="member-info">
            <div class="member-name">
              <span v-html="highlightMatch(member.username)"></span>
              <span
                class="member-id"
                v-if="member.userInfoId !== ownerId && member.userInfoId !== -1"
                >#{{ member.userInfoId }}</span
              >
            </div>
            <div class="member-status" v-if="member.status">
              <span :class="`status-dot ${member.status}`"></span>
              <span class="status-text">{{ formatStatus(member.status) }}</span>
            </div>
          </div>
        </li>
      </ul>

      <div class="no-results" v-if="!filteredMembers.length && searchQuery">
        没有找到匹配 "{{ searchQuery }}" 的成员
      </div>

      <div
        class="no-results"
        v-if="!filteredMembers.length && !searchQuery && localMembers.length"
      >
        请输入搜索关键词
      </div>

      <div class="no-results" v-if="!localMembers.length">没有成员数据</div>
    </div>
  </div>
</template>

<script>
export default {
  name: "ChatAtBox",
  props: {
    // 搜索文本
    searchText: {
      type: String,
      default: "",
    },
    // 所有者ID（用于区分自己）
    ownerId: {
      type: [Number, String],
      required: true,
    },
    // 成员列表
    members: {
      type: Array,
      default: () => [],
    },
    // 弹窗宽度
    width: {
      type: Number,
      default: 300,
    },
  },
  data() {
    return {
      // 弹窗可见性
      visible: false,
      // 弹窗位置
      position: {
        x: 0,
        y: 0,
      },
      // 搜索查询
      searchQuery: "",
      // 当前激活的索引
      activeIndex: 0,
      // 本地成员列表，避免修改 props
      localMembers: [],
      // 显示定时器
      showAtBoxTimer: null,
    };
  },
  computed: {
    // 过滤后的成员列表
    filteredMembers() {
      if (!this.searchQuery) {
        // 没有搜索词时，优先显示在线成员，然后是其他成员
        return [...this.localMembers]
          .sort((a, b) => {
            // 在线状态排序（在线 > 离开 > 离线）
            const statusOrder = { online: 3, away: 2, offline: 1 };
            return (statusOrder[b.status] || 0) - (statusOrder[a.status] || 0);
          })
          .slice(0, 10); // 最多显示10个
      }

      // 有搜索词时，进行模糊匹配
      const query = this.searchQuery.toLowerCase();
      return this.localMembers.filter((member) => {
        // 修复：使用正确的属性名
        const nameMatch = member.username.toLowerCase().includes(query);
        const idMatch = (member.userId || member.userInfoId)
          .toString()
          .includes(query);
        return nameMatch || idMatch;
      });
    },
  },
  watch: {
    // 监听外部搜索文本变化
    searchText(newVal) {
      if (this.visible) {
        this.searchQuery = newVal;
        this.activeIndex = 0; // 重置选中状态
      }
    },
    // 监听 members 变化 - 优化性能
    members: {
      handler(newMembers, oldMembers) {
        // 只在数据真正变化时重新构建
        if (this.visible && newMembers !== oldMembers) {
          this.localMembers = [
            {
              userInfoId: -1,
              username: "全体成员",
              userId: -1,
            },
            ...newMembers,
          ];
        }
      },
      deep: false, // 改为 false，避免深度监听导致的性能问题
    },
  },
  mounted() {
    // 添加全局键盘事件监听
    document.addEventListener("keydown", this.handleGlobalKeydown);
  },
  beforeDestroy() {
    // 清理事件监听
    document.removeEventListener("keydown", this.handleGlobalKeydown);
    if (this.showAtBoxTimer) {
      clearTimeout(this.showAtBoxTimer);
    }
  },
  methods: {
    // 全局键盘事件处理
    handleGlobalKeydown(e) {
      if (!this.visible) return;

      switch (e.key) {
        case "Tab":
          e.preventDefault();
          this.selectCurrent();
          break;
        case "Escape":
          this.close();
          break;
      }
    },

    // 打开弹窗
    open(position) {
      // 创建本地成员列表，包含"全体成员"选项
      this.localMembers = [
        {
          userInfoId: -1,
          username: "全体成员",
          userId: -1,
        },
        ...this.members,
      ];

      this.visible = true;
      this.position = { ...position };
      this.searchQuery = this.searchText || "";
      this.activeIndex = 0;

      // 关键：等待DOM渲染完成后，再调整位置
      this.$nextTick(() => {
        // 额外判断：确保this.$el存在且是DOM元素
        if (this.$el && typeof this.$el.getBoundingClientRect === "function") {
          this.adjustPosition(); // 此时DOM已渲染，可安全获取位置
        } else {
          console.warn("ChatAtBox 组件DOM未渲染完成，无法调整位置");
        }

        // 聚焦搜索框（同样需要DOM渲染完成）
        this.$refs.searchInput?.focus();
      });
    },

    // 关闭弹窗
    close() {
      this.visible = false;
      this.searchQuery = "";
      this.localMembers = []; // 清理本地数据
    },

    // 调整弹窗位置，确保在可视区域内
    adjustPosition() {
      if (!this.$el) return;

      const box = this.$el.getBoundingClientRect();
      const viewportWidth = window.innerWidth;
      const viewportHeight = window.innerHeight;

      let newX = this.position.x;
      let newY = this.position.y;

      // 水平方向调整
      if (newX + box.width > viewportWidth) {
        newX = Math.max(10, viewportWidth - box.width - 10);
      }

      // 垂直方向调整 - 优先向上显示
      if (newY + box.height > viewportHeight) {
        newY = Math.max(10, this.position.y - box.height - 10);
      }

      // 确保不超出视口边界
      newX = Math.max(10, Math.min(newX, viewportWidth - box.width - 10));
      newY = Math.max(10, Math.min(newY, viewportHeight - box.height - 10));

      this.position = { x: newX, y: newY };
    },

    // 选择当前激活的成员
    selectCurrent() {
      if (this.filteredMembers.length && this.activeIndex >= 0) {
        this.selectMember(this.filteredMembers[this.activeIndex]);
      }
    },

    // 选择成员
    selectMember(member) {
      if (!member || (!member.userInfoId && member.userInfoId !== -1)) {
        console.warn("无效的成员数据:", member);
        return;
      }

      this.$emit("select", member);
      this.close();
    },

    // 上移选择
    moveUp() {
      if (!this.filteredMembers.length) return;

      this.activeIndex =
        this.activeIndex <= 0
          ? this.filteredMembers.length - 1
          : this.activeIndex - 1;

      this.scrollToActive();
    },

    // 下移选择
    moveDown() {
      if (!this.filteredMembers.length) return;

      this.activeIndex =
        this.activeIndex >= this.filteredMembers.length - 1
          ? 0
          : this.activeIndex + 1;

      this.scrollToActive();
    },

    // 滚动到激活项
    scrollToActive() {
      this.$nextTick(() => {
        const activeElement = this.$el.querySelector(
          `li:nth-child(${this.activeIndex + 1})`
        );
        if (activeElement) {
          const container = this.$el.querySelector(".results-container");
          if (container) {
            const scrollTop =
              activeElement.offsetTop - container.offsetTop - 50;
            // 添加边界检查
            container.scrollTop = Math.max(
              0,
              Math.min(
                scrollTop,
                container.scrollHeight - container.clientHeight
              )
            );
          }
        }
      });
    },

    // 获取名称首字母
    getInitials(name) {
      if (!name) return "?";
      return name.charAt(0).toUpperCase();
    },

    // 高亮匹配的文本
    highlightMatch(text) {
      if (!this.searchQuery) return text;

      const query = this.searchQuery.toLowerCase();
      const index = text.toLowerCase().indexOf(query);

      if (index === -1) return text;

      // 高亮匹配的部分
      return (
        text.substring(0, index) +
        '<span class="highlight">' +
        text.substring(index, index + query.length) +
        "</span>" +
        text.substring(index + query.length)
      );
    },

    // 格式化状态文本
    formatStatus(status) {
      const statusMap = {
        online: "在线",
        away: "离开",
        offline: "离线",
      };
      return statusMap[status] || status;
    },
    getMemberKey(member, index) {
      const userId = member.userId || member.userInfoId || "";
      const username = member.username || "";
      return `member-${userId}-${username}-${index}`;
    },
  },
};
</script>

<style scoped>
.chat-at-box {
  position: fixed; /* 改为 fixed 定位，相对于视口 */
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
  z-index: 9999; /* 提高 z-index 确保在最上层 */
  overflow: hidden;
  font-size: 14px;
  /* 添加最大高度限制，防止超出屏幕 */
  max-height: 400px;
}

.search-container {
  padding: 8px 12px;
  border-bottom: 1px solid #f0f0f0;
}

.search-input {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid #e5e7eb;
  border-radius: 4px;
  outline: none;
  font-size: 14px;
  box-sizing: border-box;
  transition: border-color 0.2s;
}

.search-input:focus {
  border-color: #1677ff;
}

.results-container {
  max-height: 300px;
  overflow-y: auto;
}

.members-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.members-list li {
  padding: 10px 12px;
  cursor: pointer;
  display: flex;
  align-items: center;
  transition: background-color 0.2s;
}

.members-list li:hover,
.members-list li.active {
  background-color: #f5f7fa;
}

.member-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  overflow: hidden;
  margin-right: 12px;
  flex-shrink: 0;
}

.member-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.default-avatar {
  background-color: #e8f3ff;
  color: #1677ff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
}

.member-info {
  flex-grow: 1;
  min-width: 0;
}

.member-name {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 2px;
  font-weight: 500;
  color: #333;
}

.member-id {
  font-size: 12px;
  color: #999;
  margin-left: 8px;
  white-space: nowrap;
}

.member-status {
  display: flex;
  align-items: center;
  font-size: 12px;
  color: #666;
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 4px;
}

.status-dot.online {
  background-color: #52c41a;
}

.status-dot.away {
  background-color: #faad14;
}

.status-dot.offline {
  background-color: #d9d9d9;
}

.status-text {
  color: #888;
}

.highlight {
  color: #1677ff;
  font-weight: bold;
}

.no-results {
  padding: 20px 12px;
  text-align: center;
  color: #999;
  font-size: 14px;
}

/* 滚动条样式 */
.results-container::-webkit-scrollbar {
  width: 6px;
}

.results-container::-webkit-scrollbar-track {
  background: #f5f5f5;
}

.results-container::-webkit-scrollbar-thumb {
  background: #d9d9d9;
  border-radius: 3px;
}

.results-container::-webkit-scrollbar-thumb:hover {
  background: #b3b3b3;
}
</style>
